package com.yingjia.yingjiauniversity.json.gson;

import com.google.gson.Gson;
import com.yingjia.yingjiauniversity.json.JsonComponent;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.Map;

/**
 * <Gson转换类组件>
 *
 * @author: guoxiangxun
 * @date: 15-11-26 下午4:58
 * @version: v1.0
 */
public class GsonComponentImpl implements JsonComponent {
    private static final Charset CHARSET = Charset.forName("UTF-8");
    private Gson genericGson;
    private static volatile JsonComponent jsonComponent;

    private GsonComponentImpl() {
        genericGson = GsonFactory.build();
    }

    public static JsonComponent getInstance() {
        if (jsonComponent == null) {
            synchronized (GsonComponentImpl.class) {
                if (jsonComponent == null) {
                    jsonComponent = new GsonComponentImpl();
                }
            }
        }
        return jsonComponent;
    }

    @Override
    public <T> T toObject(String jsonString, Type c, String dateFormat) {
        T rt = null;
        Gson localGson = genericGson;
        //重新构建支持时间格式的Gson对象
        if (dateFormat != null) {
            localGson = GsonFactory.build(null, null, dateFormat);
        }
        //是否支持泛型处理
        if (c instanceof Class) {
            rt = localGson.fromJson(jsonString, (Class<T>) c);
        } else {
            rt = localGson.fromJson(jsonString, c);
        }

        return rt;
    }

    @Override
    public <T> T toObject(InputStream is, Type c, String dateFormat) {
        T rt = null;
        Gson localGson = genericGson;
        //重新构建支持时间格式的Gson对象
        if (dateFormat != null) {
            localGson = GsonFactory.build(null, null, dateFormat);
        }
        //是否支持泛型处理
        if (c instanceof Class) {
            rt = localGson.fromJson(new InputStreamReader(is, CHARSET), c);
        } else {
            rt = localGson.fromJson(new InputStreamReader(is, CHARSET), (Class<T>) c);
        }

        return rt;
    }

    @Override
    public <T> T toObject(Map map, Type c) {
        throw new UnsupportedOperationException("unsupported, please use jackson impl");
    }

    @Override
    public String toJson(Object object, String[] fields, Boolean isExclusion, String dateFormat) {
        if (isExclusion != null && isExclusion) {
            return GsonFactory.build(fields, null, dateFormat).toJson(object);
        } else if (dateFormat != null) {
            return GsonFactory.build(null, null, dateFormat).toJson(object);
        } else {
            return genericGson.toJson(object);
        }
    }

    @Override
    public Map toMap(Object object, String[] fields, Boolean isExclusion) {

        throw new UnsupportedOperationException("unsupported, please use jackson impl");
    }
}
